package controller

import (
	"digital/server/common"
	"digital/server/model"
	"fmt"
	"github.com/gin-gonic/gin"
	"log"
	"math"
	"net/http"
	"time"
)

// func GetYear(ctx *gin.Context) {
//
//		// 构建数据库查询条件
//		DB := common.GetDB()
//		DB.Where("Exist=?", 1)
//
//		var yearResults []model.YearResult
//
//		err := DB.Table("activities").Select("DISTINCT YEAR(Stime) as year").Scan(&yearResults).Error
//		if err != nil {
//			ctx.JSON(http.StatusBadRequest, gin.H{"code": 400, "message": "发生错误，请重试"})
//			log.Println("err:", err)
//			return
//		}
//
//		response.Success(ctx, gin.H{"years": yearResults}, "获取成功")
//	}
type ResponseData struct {
	Years          []int `json:"years"`
	ClubsData      []int `json:"clubsData"`
	ActivitiesData []int `json:"activitiesData"`
}

func GetStatistics(ctx *gin.Context) {
	// 构建数据库查询条件
	DB := common.GetDB()
	var clubs []model.Club
	var activities []model.Activity
	var years []int

	err := DB.Table("clubs").Where("Edate IS NOT NULL").Find(&clubs).Error
	if err != nil {
		ctx.JSON(http.StatusBadRequest, gin.H{"code": 400, "message": "查询社团数据失败"})
		log.Println("err:", err)
		return
	}

	err = DB.Table("activities").Find(&activities).Error
	if err != nil {
		ctx.JSON(http.StatusBadRequest, gin.H{"code": 400, "message": "查询活动数据失败"})
		log.Println("err:", err)
		return
	}

	// 假设数据中最早年份为2000年，最晚年份为2023年
	for year := 2019; year <= 2024; year++ {
		years = append(years, year)
	}

	clubsData := calculateClubYearlyData(years, clubs)
	activitiesData := calculateActivityYearlyData(years, activities)

	responseData := ResponseData{
		Years:          years,
		ClubsData:      clubsData,
		ActivitiesData: activitiesData,
	}

	ctx.JSON(http.StatusOK, gin.H{"data": responseData})
}

func calculateClubYearlyData(years []int, clubs []model.Club) []int {
	data := make([]int, len(years))
	for i, year := range years {
		for _, club := range clubs {
			startYear := club.Edate.Year()
			currentYear := time.Now().Year()
			endYear := currentYear
			if club.Odate != nil {
				endYear = club.Odate.Year()
			}
			if year >= startYear && year <= endYear {
				data[i]++
			}
		}
	}
	return data
}

func calculateActivityYearlyData(years []int, activities []model.Activity) []int {
	data := make([]int, len(years))
	for i, year := range years {
		for _, activity := range activities {
			startYear := activity.StartTime.Year()
			endYear := activity.EndTime.Year()
			if year >= startYear && year <= endYear {
				data[i]++
			}
		}
	}
	return data
}

func GetClubsByYear(ctx *gin.Context) {
	year := ctx.Param("year")
	DB := common.GetDB()

	var clubs []model.Club
	err := DB.Table("clubs").Where("Edate IS NOT NULL AND YEAR(Edate) <= ? AND (YEAR(Odate) >= ? OR Odate IS NULL)", year, year).Find(&clubs).Error
	if err != nil {
		ctx.JSON(http.StatusBadRequest, gin.H{"code": 400, "message": "查询社团数据失败"})
		log.Println("err:", err)
		return
	}
	for _, club := range clubs {
		fmt.Println(club.Cid)
	}
	clubMembersCount := make(map[uint]int)
	clubMembersUIDs := make(map[uint][]int)
	clubMembersGender0 := make(map[uint]int)                  //男生人数
	clubMembersGender1 := make(map[uint]int)                  // 女生人数
	clubMembersGender0Ratio := make(map[uint]float64)         //男生占比
	clubMembersGender1Ratio := make(map[uint]float64)         // 女生占比
	clubMembersGenderCount := make(map[uint]map[string]int)   // 性别分布
	clubMembersPolitics := make(map[uint]int)                 // 党员人数
	clubMembersPoliticsRatio := make(map[uint]float64)        // 党员占比
	clubActivitiesCount := make(map[uint]int)                 // 举办活动数
	clubMembersPoliticsCount := make(map[uint]map[string]int) // 政治面貌分布
	clubMembersGradeCount := make(map[uint]map[string]int)    // 年级分布
	clubMembersMajorCount := make(map[uint]map[string]int)    // 专业分布

	for _, club := range clubs {
		var memberCount int64
		err := DB.Table("user_clubs").Where("Cid = ? AND YEAR(JTime) <= ? AND (QTime IS NULL OR YEAR(QTime) >= ?)", club.Cid, year, year).Count(&memberCount).Error
		if err != nil {
			ctx.JSON(http.StatusBadRequest, gin.H{"code": 400, "message": "查询社团成员数据失败"})
			log.Println("err:", err)
			return
		}
		clubMembersCount[uint(club.Cid)] = int(memberCount)

		var activitiesCount int64
		err = DB.Table("activities").Where("Cid = ? AND YEAR(StartTime) <= ? AND (EndTime IS NULL OR YEAR(EndTime) >= ?)", club.Cid, year, year).Count(&activitiesCount).Error
		if err != nil {
			ctx.JSON(http.StatusBadRequest, gin.H{"code": 400, "message": "查询社团成员数据失败"})
			log.Println("err:", err)
			return
		}
		clubActivitiesCount[uint(club.Cid)] = int(activitiesCount)

		var userclubs []model.UserClub
		err = DB.Where("Cid = ? AND YEAR(JTime) <= ? AND (QTime IS NULL OR YEAR(QTime) >= ?)", club.Cid, year, year).Find(&userclubs).Error
		if err != nil {
			ctx.JSON(http.StatusBadRequest, gin.H{"code": 400, "message": "查询社团成员UID数据失败"})
			log.Println("err:", err)
			return
		}
		var uids []int
		for _, uc := range userclubs {
			uids = append(uids, uc.UID)
		}
		clubMembersUIDs[uint(club.Cid)] = uids

		// 获取成员性别和政治面貌信息
		var users []model.User
		err = DB.Table("users").Select("gender, major, grade,politics_status").Where("uid IN (?)", uids).Find(&users).Error
		if err != nil {
			ctx.JSON(http.StatusBadRequest, gin.H{"code": 400, "message": "查询用户数据失败"})
			log.Println("err:", err)
			return
		}
		var gender0Count, gender1Count, partyMemberCount int64
		gradeCount := make(map[string]int)
		politicsCount := make(map[string]int)
		genderCount := make(map[string]int)
		majorCount := make(map[string]int)
		for _, user := range users {
			if user.Gender == 0 {
				gender0Count++
				genderCount["男生"]++
			} else {
				gender1Count++
				genderCount["女生"]++
			}
			if user.PoliticsStatus == "党员" {
				partyMemberCount++
			}
			gradeCount[user.Grade]++
			politicsCount[user.PoliticsStatus]++
			majorCount[user.Major]++
		}

		totalMembers := float64(clubMembersCount[uint(club.Cid)])
		clubMembersGender0[uint(club.Cid)] = int(gender0Count) // 男生人数
		clubMembersGender1[uint(club.Cid)] = int(gender1Count) // 女生人数
		if totalMembers > 0 {
			clubMembersGender0Ratio[uint(club.Cid)] = math.Round((float64(gender0Count)/totalMembers*100)*10) / 10      // 男生占比
			clubMembersGender1Ratio[uint(club.Cid)] = math.Round((float64(gender1Count)/totalMembers*100)*10) / 10      // 女生占比
			clubMembersPoliticsRatio[uint(club.Cid)] = math.Round((float64(partyMemberCount)/totalMembers*100)*10) / 10 // 党员占比
		} else {
			clubMembersGender0Ratio[uint(club.Cid)] = 0
			clubMembersGender1Ratio[uint(club.Cid)] = 0
			clubMembersPoliticsRatio[uint(club.Cid)] = 0
		}
		clubMembersPolitics[uint(club.Cid)] = int(partyMemberCount) // 党员人数
		clubMembersGradeCount[uint(club.Cid)] = gradeCount
		clubMembersPoliticsCount[uint(club.Cid)] = politicsCount
		clubMembersMajorCount[uint(club.Cid)] = majorCount
		clubMembersGenderCount[uint(club.Cid)] = genderCount
	}

	var responseClubs []map[string]interface{}
	for _, club := range clubs {
		clubData := map[string]interface{}{
			"Cid":              club.Cid,
			"Cname":            club.Cname,
			"Type":             club.Type,
			"Size":             clubMembersCount[uint(club.Cid)],
			"UIDs":             clubMembersUIDs[uint(club.Cid)],
			"Gender0Count":     clubMembersGender0[uint(club.Cid)],       // 男生人数
			"Gender1Count":     clubMembersGender1[uint(club.Cid)],       // 女生人数
			"Gender0Ratio":     clubMembersGender0Ratio[uint(club.Cid)],  // 男生占比
			"Gender1Ratio":     clubMembersGender1Ratio[uint(club.Cid)],  // 女生占比
			"GenderCount":      clubMembersGenderCount[uint(club.Cid)],   // 男女分布
			"PartyMemberCount": clubMembersPolitics[uint(club.Cid)],      // 党员人数
			"PartyMemberRatio": clubMembersPoliticsRatio[uint(club.Cid)], // 党员占比
			"Activities":       clubActivitiesCount[uint(club.Cid)],      //该年该社团举办活动数
			"PoliticsCount":    clubMembersPoliticsCount[uint(club.Cid)], // 党员分布
			"GradeCount":       clubMembersGradeCount[uint(club.Cid)],    // 年级分布
			"MajorCount":       clubMembersMajorCount[uint(club.Cid)],    // 专业分布
		}
		responseClubs = append(responseClubs, clubData)
	}

	ctx.JSON(http.StatusOK, gin.H{"data": responseClubs})
}

func GetActivitiesByYear(ctx *gin.Context) {
	year := ctx.Param("year")
	DB := common.GetDB()
	var activities []model.Activity
	err := DB.Table("activities").Where("YEAR(StartTime) <= ? AND YEAR(EndTime) >= ?", year, year).Find(&activities).Error
	if err != nil {
		ctx.JSON(http.StatusBadRequest, gin.H{"code": 400, "message": "查询活动数据失败"})
		log.Println("err:", err)
		return
	}

	activityMembersCount := make(map[uint]int)
	activityMembersUIDs := make(map[uint][]int)
	activityMembersGender0 := make(map[uint]int)                  //男生人数
	activityMembersGender1 := make(map[uint]int)                  // 女生人数
	activityMembersGender0Ratio := make(map[uint]float64)         //男生占比
	activityMembersGender1Ratio := make(map[uint]float64)         // 女生占比
	activityMembersGenderCount := make(map[uint]map[string]int)   // 性别分布
	activityMembersPolitics := make(map[uint]int)                 // 党员人数
	activityMembersPoliticsRatio := make(map[uint]float64)        // 党员占比
	activityMembersPoliticsCount := make(map[uint]map[string]int) // 政治面貌分布
	activityMembersGradeCount := make(map[uint]map[string]int)    // 年级分布
	activityMembersMajorCount := make(map[uint]map[string]int)    // 专业分布

	for _, activity := range activities {
		var memberCount int64
		err := DB.Table("activity_users").Where("Aid = ? ", activity.Aid).Count(&memberCount).Error
		if err != nil {
			ctx.JSON(http.StatusBadRequest, gin.H{"code": 400, "message": "查询活动成员数据失败"})
			log.Println("err:", err)
			return
		}
		activityMembersCount[uint(activity.Aid)] = int(memberCount)

		var useractivities []model.ActivityUser
		err = DB.Where("Aid = ? ", activity.Aid).Find(&useractivities).Error
		if err != nil {
			ctx.JSON(http.StatusBadRequest, gin.H{"code": 400, "message": "查询社团成员UID数据失败"})
			log.Println("err:", err)
			return
		}
		var uids []int
		for _, ua := range useractivities {
			uids = append(uids, ua.UID)
		}
		activityMembersUIDs[uint(activity.Aid)] = uids

		// 获取成员性别和政治面貌信息
		var users []model.User
		err = DB.Table("users").Select("gender, politics_status, grade, major").Where("uid IN (?)", uids).Find(&users).Error
		if err != nil {
			ctx.JSON(http.StatusBadRequest, gin.H{"code": 400, "message": "查询用户数据失败"})
			log.Println("err:", err)
			return
		}
		var gender0Count, gender1Count, partyMemberCount int64
		gradeCount := make(map[string]int)
		politicsCount := make(map[string]int)
		genderCount := make(map[string]int)
		majorCount := make(map[string]int)
		for _, user := range users {
			if user.Gender == 0 {
				gender0Count++
				genderCount["男生"]++
			} else {
				gender1Count++
				genderCount["女生"]++
			}
			if user.PoliticsStatus == "党员" {
				partyMemberCount++
			}
			gradeCount[user.Grade]++
			politicsCount[user.PoliticsStatus]++
			majorCount[user.Major]++
		}

		totalMembers := float64(activityMembersCount[uint(activity.Aid)])
		activityMembersGender0[uint(activity.Aid)] = int(gender0Count) // 男生人数
		activityMembersGender1[uint(activity.Aid)] = int(gender1Count) // 女生人数
		if totalMembers > 0 {
			activityMembersGender0Ratio[uint(activity.Aid)] = math.Round((float64(gender0Count)/totalMembers*100)*10) / 10      // 男生占比
			activityMembersGender1Ratio[uint(activity.Aid)] = math.Round((float64(gender1Count)/totalMembers*100)*10) / 10      // 女生占比
			activityMembersPoliticsRatio[uint(activity.Aid)] = math.Round((float64(partyMemberCount)/totalMembers*100)*10) / 10 // 党员占比
		} else {
			activityMembersGender0Ratio[uint(activity.Aid)] = 0
			activityMembersGender1Ratio[uint(activity.Aid)] = 0
			activityMembersPoliticsRatio[uint(activity.Aid)] = 0
		}
		activityMembersPolitics[uint(activity.Aid)] = int(partyMemberCount) // 党员人数
		activityMembersGradeCount[uint(activity.Aid)] = gradeCount
		activityMembersPoliticsCount[uint(activity.Aid)] = politicsCount
		activityMembersMajorCount[uint(activity.Aid)] = majorCount
		activityMembersGenderCount[uint(activity.Aid)] = genderCount
	}
	var responseActivities []map[string]interface{}
	for _, activity := range activities {
		activityData := map[string]interface{}{
			"Aid":              activity.Aid,
			"ATitle":           activity.ATitle,
			"Type":             activity.Type,
			"Size":             activityMembersCount[uint(activity.Aid)],
			"Gender0Count":     activityMembersGender0[uint(activity.Aid)],       // 男生人数
			"Gender1Count":     activityMembersGender1[uint(activity.Aid)],       // 女生人数
			"Gender0Ratio":     activityMembersGender0Ratio[uint(activity.Aid)],  // 男生占比
			"Gender1Ratio":     activityMembersGender1Ratio[uint(activity.Aid)],  // 女生占比
			"GenderCount":      activityMembersGenderCount[uint(activity.Aid)],   // 男女分布
			"PartyMemberCount": activityMembersPolitics[uint(activity.Aid)],      // 党员人数
			"PartyMemberRatio": activityMembersPoliticsRatio[uint(activity.Aid)], // 党员占比
			"PoliticsCount":    activityMembersPoliticsCount[uint(activity.Aid)], // 党员分布
			"GradeCount":       activityMembersGradeCount[uint(activity.Aid)],    // 年级分布
			"MajorCount":       activityMembersMajorCount[uint(activity.Aid)],    // 专业分布
		}
		responseActivities = append(responseActivities, activityData)
	}

	ctx.JSON(http.StatusOK, gin.H{"data": responseActivities})
}
